#include "vkchecker.h"
// Qt
#include <QPainter>
#include <QFontMetrics>
#include <QSizeF>
#include <qtimer.h>
#include <qgraphicsview.h>
// KDE
#include <KLocale>
#include <kconfigdialog.h>
#include <kwallet.h>
#include <kstringhandler.h>
#include <kmessagebox.h>

#include <plasma/svg.h>
#include <plasma/theme.h>

const QString VKChecker::walletFolder("Plasma-VKChecker");

VKChecker::VKChecker(QObject *parent, const QVariantList &args)
    : Plasma::Applet(parent, args),
      m_wallet(0),
      m_pollingTimer(new QTimer),
      m_client(new VKClient(0))
{
    kDebug() << "called.";
    setBackgroundHints(NoBackground);
    setHasConfigurationInterface(true);  
    resize(200, 200);
}

VKChecker::~VKChecker()
{
    kDebug() << "called.";
    if (hasFailedToLaunch()) {
        // Do some cleanup here
    } else {
        // Save settings
    }
}

void VKChecker::init()
{
	// TODO: UI
	connect(m_pollingTimer, SIGNAL(timeout()), SLOT(poll()));
	
	// Reading configs from configuration file
	KConfigGroup cg = config();
	m_login = cg.readEntry("login");
	m_password = KStringHandler::obscure(cg.readEntry("password"));
	m_pollingTime = cg.readEntry("pollingTime", 30);
	
	// Wallet
	if (m_login.isEmpty())
	{
		kDebug() << "login is empty, configuration required";
		setConfigurationRequired(true); 
	}
	else if (m_password.isEmpty())
	{
		kDebug() << "password from config is empty, trying to load wallet for user" << m_login;
		getWallet(SLOT(readWallet(bool)));
	}
	else 
	{
		kDebug() << "login and password are in config file, trying to use it";
		startPolling();
	}
}

void VKChecker::getWallet(const char* slot)
{	
	QGraphicsView *v = view();
	WId w = 0;
	if (v) 
	{
		w = v->winId();
	}
	
	kDebug() << "creating wallet";
	m_wallet = KWallet::Wallet::openWallet(KWallet::Wallet::NetworkWallet(),
						w, KWallet::Wallet::Asynchronous);
	connect(m_wallet, SIGNAL(walletOpened(bool)), slot);
}

void VKChecker::readWallet(bool success)
{
	kDebug() << "called" << success;
	QString pwd;
	if (success && setFolder(VKChecker::walletFolder) && (m_wallet->readPassword(m_login, pwd) == 0)) 
	{
		kDebug() << "using password from wallet";
		m_password = pwd;
		startPolling();
	} 
	else if (m_password.isEmpty())
	{
		setConfigurationRequired(true, i18n("Failed to load password from wallet or config file"));
		kDebug() << "failed to read password from wallet";
	}
	delete m_wallet;
}

void VKChecker::writeWallet(bool success)
{
	kDebug() << "called" << success;
	if (success && setFolder(VKChecker::walletFolder) && (m_wallet->writePassword(m_login, m_password) == 0))
	{
		kDebug() << "we put password in wallet, so removing it from config file";
		config().deleteEntry("password");
		emit configNeedsSaving();
	}
	else
	{
		kDebug() << "failed to store password in wallet, using config file";
		if (KMessageBox::warningYesNo(0, i18n("Failed to access wallet. Do you want to use config file instead? (it is unsecure!)"))
			== KMessageBox::Yes)
		{
			config().writeEntry("password", KStringHandler::obscure(m_password));
		}
	}
}

void VKChecker::startPolling()
{
	kDebug() << "called.";
	m_client->setLoginInfo(m_login, m_password);
	m_pollingTimer->setInterval(m_pollingTime*1000);
	m_pollingTimer->start();
}

void VKChecker::poll()
{
	m_client->checkMail();
}

bool VKChecker::setFolder(const QString &folder)
{
	m_wallet->createFolder(folder);
	if ( !m_wallet->setFolder(folder) )
	{
		kDebug() << "failed to set wallet folder" << folder;
		return false;
	}
	
	kDebug() << "using wallet folder" << folder;
	return true;
}

void VKChecker::createConfigurationInterface(KConfigDialog* parent)
{
	kDebug() << "called.";
	
	Plasma::Applet::createConfigurationInterface(parent);
	connect(parent, SIGNAL(applyClicked()), this, SLOT(configAccepted()));
	connect(parent, SIGNAL(okClicked()), this, SLOT(configAccepted()));
	
	QWidget *configWidget = new QWidget;
	configUi.setupUi(configWidget);
	configUi.loginEdit->setText(m_login);
	configUi.passwordEdit->setText(m_password);
	// TODO: polling interval
	
	parent->addPage(configWidget, i18n("General"), icon());
}

void VKChecker::configAccepted()
{
	kDebug() << "called.";
	QString login = configUi.loginEdit->text();
	QString password = configUi.passwordEdit->text();
	int pollingTime = configUi.pollingTimeBox->value();	
	
	bool changed = false;
	bool reloginRequired = true;
	KConfigGroup cg = config();
	
	if (login != m_login)
	{
		changed = true;
		reloginRequired = true;
		m_login = login;
		cg.writeEntry("login", login);
	}
	
	if (password != m_password)
	{
		changed = true;
		reloginRequired = true;
		m_password = password;
	}
	
	if (!m_login.isEmpty() && (changed || m_password.isEmpty()))
	{
		// If login or password changed, we need to reload wallet
		// if login changed, we need to see is there a password for new login in wallet
		// else we need to write there a new password
		getWallet(password.isEmpty() ? SLOT(readWallet(bool)) : SLOT(writeWallet(bool)));
	}
	// TODO: other configs
	
	if (pollingTime != m_pollingTime)
	{
		changed = true;
		m_pollingTime = pollingTime;
		m_pollingTimer->setInterval(m_pollingTime*1000);
	}
	
	if (changed)
	{
		if (reloginRequired)
		{
			startPolling();
		}
		
		emit configNeedsSaving();
	}
	
	setConfigurationRequired(m_login.isEmpty());
}

void VKChecker::paintInterface(QPainter *p,
	  const QStyleOptionGraphicsItem *option, const QRect &contentsRect)
{
	
	p->setRenderHint(QPainter::SmoothPixmapTransform);
	p->setRenderHint(QPainter::Antialiasing);

	// We place the icon and text
	p->save();
	p->setPen(Qt::white);
	p->drawText(contentsRect,
			Qt::AlignBottom | Qt::AlignHCenter,
			i18n("Hello Plasmoid!"));
	p->restore();
}

#include "vkchecker.moc"
